import os
import random
import string

from PIL import Image, ImageFont, ImageDraw, ImageFilter


class ImageVerify:
    def __init__(self, width=140, height=40, length=4, size=28):
        """
        初始化
        :param width:图片宽度
        :param height:图片高度
        :param length:字符长度
        :param size:字符大小
        """
        self.width = width
        self.height = height
        self.length = length
        self.size = size

    def random_str(self):
        """
        验证码上要生成的 随机的字符串
        10个数字26个小写字母和26个大写字母
        :return:随机字符串
        """

        source = string.digits + string.ascii_letters
        return ''.join(random.sample(source, self.length))

    # 随机颜色
    def random_color(self, start=0, end=255):
        """
        随机颜色RGB
        :param start: 起始值
        :param end: 结束值
        :return: tuple(r, g, b)
        """

        # 实现：拿到的数是一个元组  使用方法：列表推导式
        res = (random.randint(0, 255) for i in range(3))
        return tuple(res)

    # 干扰线
    def random_lines(self, drew):
        """
        绘制干扰线
        两点决定一条线
        一个点(x或y)决定
        一条线(x,y)决定
        :param drew: 两笔对象
        :return:
        """
        linewidth = random.randint(1, 2)
        for i in range(self.length):  # 确定画几条线 0,1,2,3
            lines = [(random.randint(0, self.width), random.randint(0, self.height)) for i in range(2)]
            # 用画笔将随机两点用fill颜色连成一条2px的线
            drew.line(list(lines), fill=self.random_color(start=200), width=linewidth)

    # 干扰点
    def random_points(self, drew, rate):
        """
        绘制干扰点(x, y)
        :param drew: 画笔对象
        :param rate: 出现频率
        :return:
        """
        for x in range(self.width):  # x轴取值
            for y in range(self.height):  # y取值
                if random.randint(0, 100) < rate:  # 控制条件,满足条件才能用随机fill去画点
                    drew.point((x, y), fill=self.random_color(start=150))

    # 定义方法生成画布
    def image_code(self):
        """
        生成验证码图片
        :return:
        """
        image = Image.new('RGB', (self.width, self.height), (255, 255, 255))

        # 创建并实例化Font(字体)对象
        # font = ImageFont.truetype('utils/HYYakuHei-85W.ttf', self.size)  # 不推荐,字体路径写死了
        # 当前文件的绝对路径
        file = os.path.dirname(os.path.abspath(__file__))  # '/home/bd/py18/LMS/utils/verifyUtil.py'
        font = ImageFont.truetype(f'{file}/HYYakuHei-85W.ttf', self.size)

        # 创建draw(画笔)对象
        draw = ImageDraw.Draw(image)

        # 随机生成字符串
        code = self.random_str()

        # 将字符串画上画布
        for t in range(self.length):  # 0,1,2,3
            # 将验证码中每个字符在(30 * t, 3)坐标处开始,用fill颜色,用font字体画出
            draw.text((30 * t + 15, 3), code[t], font=font, fill=self.random_color(start=0, end=64))  # 位置：0, 3; 30, 3;60, 3;90, 3

        # 用画笔画干扰线(画东西就得带画笔)
        self.random_lines(draw)

        # 用画笔画干扰点
        self.random_points(draw, 20)

        # 模糊干扰
        # image = image.filter(ImageFilter.BLUR)

        return image, code


# 首先被执行的首文件，不能被导入
# if __name__ == '__main__':
#     imgVerify = ImageVerify()
#     img = imgVerify.image_code()
#     with open('test.png', 'wb') as f:
#         img.save(f)
